package com.wei.czz.common.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wei.czz.common.constant.Constant;
import com.wei.czz.common.exception.CzzException;
import com.wei.czz.framework.security.entity.SecurityUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * Created by IntelliJ IDEA.
 *
 * @author wyw
 * date: 2025-04-30 17:44:22
 * className: ContextUtils 上下文参数工具类
 * version: 1.0
 * description:
 */
public class ContextUtils {

    private static final Logger log = LoggerFactory.getLogger(ContextUtils.class);

    private static final ThreadLocal<Map<String, Object>> context = ThreadLocal.withInitial(HashMap::new);

    private static final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 批量设置上下文参数
     *
     * @param contextMap 上下文参数映射
     */
    public static void set(Map<String, Object> contextMap) {
        context.get().putAll(contextMap);
    }

    /**
     * 设置上下文参数
     *
     * @param key   键
     * @param value 值
     */
    public static void set(String key, Object value) {
        context.get().put(key, value);
    }

    /**
     * 获取所有上下文参数映射
     *
     * @return 上下文参数映射
     */
    public static Map<String, Object> get() {
        return context.get();
    }

    /**
     * 获取上下文参数
     *
     * @param key 键
     * @return 值
     */
    @SuppressWarnings(value = { "unchecked" })
    public static <T> T get(String key) {
        return (T) context.get().get(key);
    }

    /**
     * 获取上下文参数映射副本
     *
     * @return 上下文参数映射副本
     */
    public static Map<String, Object> getCopy() {
        Map<String, Object> contextMap = context.get();
        if (contextMap.isEmpty()) {
            return new HashMap<>();
        }

        // 特殊处理登录对象
        SecurityUser securityUser = (SecurityUser) contextMap.remove(Constant.SECURITY_USER);

        // 深拷贝
        Map<String, Object> copyContextMap = parseJson(toJsonString(contextMap), new TypeReference<>() {});

        // 特殊处理登录对象
        if (Objects.nonNull(securityUser)) {
            contextMap.put(Constant.SECURITY_USER, securityUser);
            copyContextMap.put(Constant.SECURITY_USER, securityUser);
        }

        return copyContextMap;
    }

    /**
     * 移除上下文参数
     */
    public static void remove() {
        context.remove();
    }

    /**
     * 对象序列化
     * @param object 参数对象
     * @return json格式字符串
     */
    private static String toJsonString(Object object) {
        try {
            return objectMapper.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            log.error("【上下文参数工具类】对象序列化异常。message={}", e.getMessage(), e);
            throw new CzzException();
        }
    }

    /**
     * json字符串反序列化
     * @param value         值
     * @param typeReference 自定义类型转换方式
     * @return 类型对象
     * @param <T> 泛型
     */
    private static <T> T parseJson(String value, TypeReference<T> typeReference) {
        try {
            return objectMapper.readValue(value, typeReference);
        } catch (JsonProcessingException e) {
            log.error("【上下文参数工具类】字符串反序列化异常。message={}", e.getMessage(), e);
            throw new CzzException();
        }
    }
}
